#include "window.h"
#include "filterDialog.h"
#include "operationDialog.h"
#include "representationDialog.h"
#include "pcaDialog.h"
#include "../src/spatialFilter.h"

Window::Window(){
	setWindowTitle(tr("[PDI] EDITOR"));
    statusBar()->showMessage(tr(""));
    setUnifiedTitleAndToolBarOnMac(true);
    openInNewTab = false;

	createPanels();
	createActions();
	createMenus();

    tab = new QTabWidget(this);
    tab->setTabsClosable(true);
    connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(closeImage(int)));
    connect(tab, SIGNAL(currentChanged(int)), this, SLOT(updateImage(int)));
    setCentralWidget(tab);
    resize(700, 500);
}

Window::~Window(){
}

void Window::createMenus(){
    QMenu *fileMenu;
    QMenu *editMenu;
    QMenu *viewMenu;
    QMenu *zoomMenu;
    QMenu *operationMenu;
    QMenu *spacialFilterMenu;
    QMenu *transformFilterMenu;
    QMenu *histogramFilterMenu;
    QMenu *blurFilterMenu;
    QMenu *sharpFilterMenu;
    QMenu *representationMenu;

    fileMenu = menuBar()->addMenu(QString::fromUtf8("&Arquivo"));
    fileMenu->addAction(openAct);
    fileMenu->addAction(saveAct);
    fileMenu->addAction(saveAsAct);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAct);


    editMenu = menuBar()->addMenu(QString::fromUtf8("&Editar"));
    editMenu->addAction(openInNewTabAct);
    editMenu->addSeparator();
    editMenu->addAction(operationAct);
    editMenu->addAction(filterAct);
    editMenu->addAction(representationAct);
    editMenu->addSeparator();

    operationMenu = editMenu->addMenu(QString::fromUtf8("&Operações"));
    operationMenu->addAction(additionAct);
    operationMenu->addAction(subtractionAct);
    operationMenu->addAction(multiplicationAct);
    operationMenu->addAction(divisionAct);

    spacialFilterMenu = editMenu->addMenu(tr("&Filtros Espaciais"));

    transformFilterMenu = spacialFilterMenu->addMenu(QString::fromUtf8("&Transformações"));
    transformFilterMenu->addAction(grayscaleAct);
    transformFilterMenu->addAction(negativeAct);
    transformFilterMenu->addAction(logAct);
    transformFilterMenu->addAction(powerAct);
    transformFilterMenu->addAction(thresholdingAct);

    histogramFilterMenu = spacialFilterMenu->addMenu(QString::fromUtf8("&Histograma"));
    histogramFilterMenu->addAction(histogramEqualizationAct);
    histogramFilterMenu->addAction(histogramMatchingAct);
    histogramFilterMenu->addAction(localHistogramProcessingAct);
    histogramFilterMenu->addAction(localHistogramProcessingWithStatisticsAct);

    blurFilterMenu = spacialFilterMenu->addMenu(QString::fromUtf8("&Suavização"));
    blurFilterMenu->addAction(averageAct);
    blurFilterMenu->addAction(weightedAverageAct);
    blurFilterMenu->addAction(gaussianAct);
    blurFilterMenu->addAction(orderStatisticAct);

    sharpFilterMenu = spacialFilterMenu->addMenu(QString::fromUtf8("&Realce"));
    sharpFilterMenu->addAction(laplacianAct);
    sharpFilterMenu->addAction(unsharpMaskingAndHighBoostFilterAct);
    sharpFilterMenu->addAction(gradientAct);


    representationMenu = editMenu->addMenu(QString::fromUtf8("&Representação e Descritores"));
    representationMenu->addAction(boundaryFollowingAct);
    representationMenu->addAction(chainCodeAct);
    representationMenu->addAction(splittingAct);
    representationMenu->addAction(basicDescriptorsAct);
    representationMenu->addAction(momentInvariantsDescriptorsAct);
    representationMenu->addAction(histogramDescriptorsAct);

    editMenu->addAction(pcaAct);


    viewMenu = menuBar()->addMenu(QString::fromUtf8("&Vizualizar"));
    viewMenu->addAction(viewHistogramPanelAct);
    viewMenu->addSeparator();

    zoomMenu = viewMenu->addMenu(tr("Zoom"));
    zoomMenu->addAction(normalSizeAct);
    zoomMenu->addAction(zoomInAct);
    zoomMenu->addAction(zoomOutAct);
    zoomMenu->addAction(fitToWindowAct);
}

void Window::createPanels(){
    histogramPanel = NULL;
    histogramPanelDock = new QDockWidget(tr("Histograma"),this);
    histogramPanelDock->setFixedSize(QSize(265, 185));
	histogramPanelDock->setWidget(histogramPanel);
    addDockWidget(Qt::RightDockWidgetArea, histogramPanelDock);
}

void Window::createActions(){
    openAct = new QAction(QString::fromUtf8("Abrir"), this);
    openAct->setShortcuts(QKeySequence::Open);
    openAct->setStatusTip(QString::fromUtf8("Abrir uma nova imagem."));
    connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

    saveAct = new QAction(QString::fromUtf8("Salvar"), this);
    saveAct->setShortcuts(QKeySequence::Save);
    saveAct->setStatusTip(QString::fromUtf8("Salvar imagem atual."));
    saveAct->setEnabled(false);
    connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));

    saveAsAct = new QAction(QString::fromUtf8("Salvar como"), this);
    saveAsAct->setShortcuts(QKeySequence::SaveAs);
    saveAsAct->setStatusTip(QString::fromUtf8("Salvar imagem atual em um arquivo com outro nome."));
    saveAsAct->setEnabled(false);
    connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));

    exitAct = new QAction(QString::fromUtf8("Sair"), this);
    exitAct->setShortcuts(QKeySequence::Quit);
    exitAct->setStatusTip(QString::fromUtf8("Sair da aplicação."));
    connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));

    filterAct = new QAction(QString::fromUtf8("Galeria de filtros"), this);
	filterAct->setShortcut(tr("Ctrl+Shift+F"));
    filterAct->setStatusTip(QString::fromUtf8("Abrir galeria de filtros."));
    filterAct->setEnabled(false);
    connect(filterAct, SIGNAL(triggered()), this, SLOT(filterDlg()));

    operationAct = new QAction(QString::fromUtf8("Galeria de operações"), this);
//	operationAct->setShortcut(tr("Ctrl+Shift+F"));
    operationAct->setStatusTip(QString::fromUtf8("Abrir galeria de operações bnárias."));
    operationAct->setEnabled(false);
    connect(operationAct, SIGNAL(triggered()), this, SLOT(operationDlg()));

    representationAct = new QAction(QString::fromUtf8("Galeria de representações"), this);
//	representationAct->setShortcut(tr("Ctrl+Shift+F"));
    representationAct->setStatusTip(QString::fromUtf8("Abrir galeria de representações de imagens."));
    representationAct->setEnabled(false);
    connect(representationAct, SIGNAL(triggered()), this, SLOT(representationDlg()));

    pcaAct = new QAction(QString::fromUtf8("Componentes principais"), this);
//	pcaAct->setShortcut(tr("Ctrl+Shift+F"));
    pcaAct->setStatusTip(QString::fromUtf8("Testar as componentes principais."));
    pcaAct->setEnabled(false);
    connect(pcaAct, SIGNAL(triggered()), this, SLOT(pcaDlg()));

    normalSizeAct = new QAction(QString::fromUtf8("Tamanho original"), this);
    normalSizeAct->setStatusTip(QString::fromUtf8("Colocar zoom em 100%."));
    normalSizeAct->setEnabled(false);
    connect(normalSizeAct, SIGNAL(triggered()), this, SLOT(normalSize()));

    zoomInAct = new QAction(QString::fromUtf8("Aumentar zoom"), this);
    zoomInAct->setStatusTip(QString::fromUtf8("Aumentar zoom em 25%."));
    zoomInAct->setEnabled(false);
    connect(zoomInAct, SIGNAL(triggered()), this, SLOT(zoomIn()));

    zoomOutAct = new QAction(QString::fromUtf8("Diminuir zoom"), this);
    zoomOutAct->setStatusTip(QString::fromUtf8("Diminuir zoom em 25%."));
    zoomOutAct->setEnabled(false);
    connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(zoomOut()));

    fitToWindowAct = new QAction(QString::fromUtf8("Ajustar na janela"), this);
    fitToWindowAct->setStatusTip(QString::fromUtf8("Mudar zoom para a imagem se ajustr a janela."));
    fitToWindowAct->setEnabled(false);
    connect(fitToWindowAct, SIGNAL(triggered()), this, SLOT(fitToWindow()));

	viewHistogramPanelAct = histogramPanelDock->toggleViewAction();
    viewHistogramPanelAct->setEnabled(false);
	histogramPanelDock->hide();

    openInNewTabAct = new QAction(QString::fromUtf8("Modificações em nova aba"), this);
    openInNewTabAct->setStatusTip(QString::fromUtf8("Abrir imagem modificada em nova aba."));
    openInNewTabAct->setCheckable(true);
    openInNewTabAct->setChecked(openInNewTab);
    connect(openInNewTabAct, SIGNAL(toggled(bool)), this, SLOT(changeOpenInNewTab(bool)));


    grayscaleAct = new QAction(QString::fromUtf8("Grayscale"), this);
    grayscaleAct->setStatusTip(QString::fromUtf8("Deixa a imagem com as cores em escala de cinza."));
    grayscaleAct->setEnabled(false);
    connect(grayscaleAct, SIGNAL(triggered()), this, SLOT(openGrayscaleFilter()));

    negativeAct = new QAction(QString::fromUtf8("Negativo"), this);
    negativeAct->setStatusTip(QString::fromUtf8("Deixa a imagem com as cores invertidas."));
    negativeAct->setEnabled(false);
    connect(negativeAct, SIGNAL(triggered()), this, SLOT(openNegativeFilter()));

    logAct = new QAction(QString::fromUtf8("Logaritmo"), this);
    logAct->setStatusTip(QString::fromUtf8("Deixa a imagem mais clara."));
    logAct->setEnabled(false);
    connect(logAct, SIGNAL(triggered()), this, SLOT(openLogFilter()));

    powerAct = new QAction(QString::fromUtf8("Potência"), this);
    powerAct->setStatusTip(QString::fromUtf8("Deixa a imagem mais clara ou mais escura."));
    powerAct->setEnabled(false);
    connect(powerAct, SIGNAL(triggered()), this, SLOT(openPowerFilter()));

    thresholdingAct = new QAction(QString::fromUtf8("Limiar"), this);
    thresholdingAct->setStatusTip(QString::fromUtf8("Deixa a imagem preta e branca."));
    thresholdingAct->setEnabled(false);
    connect(thresholdingAct, SIGNAL(triggered()), this, SLOT(openThresholdingFilter()));

    histogramEqualizationAct = new QAction(QString::fromUtf8("Equalização"), this);
    histogramEqualizationAct->setStatusTip(QString::fromUtf8("Tenta deixar a imagem mais balanceada."));
    histogramEqualizationAct->setEnabled(false);
    connect(histogramEqualizationAct, SIGNAL(triggered()), this, SLOT(openHistogramEqualizationFilter()));

    histogramMatchingAct = new QAction(QString::fromUtf8("Especificação"), this);
    histogramMatchingAct->setStatusTip(QString::fromUtf8("Tenta balencear a magem de acordo com a entrada."));
    histogramMatchingAct->setEnabled(false);
    connect(histogramMatchingAct, SIGNAL(triggered()), this, SLOT(openHistogramMatchingFilter()));

    localHistogramProcessingAct = new QAction(QString::fromUtf8("Equalização local"), this);
    localHistogramProcessingAct->setStatusTip(QString::fromUtf8("Faz a equalização local."));
    localHistogramProcessingAct->setEnabled(false);
    connect(localHistogramProcessingAct, SIGNAL(triggered()), this, SLOT(openLocalHistogramProcessingFilter()));

    localHistogramProcessingWithStatisticsAct = new QAction(QString::fromUtf8("Realce com estatísticas"), this);
    localHistogramProcessingWithStatisticsAct->setStatusTip(QString::fromUtf8("Usa estatística da média para realçar a imagem."));
    localHistogramProcessingWithStatisticsAct->setEnabled(false);
    connect(localHistogramProcessingWithStatisticsAct, SIGNAL(triggered()), this, SLOT(openLocalHistogramProcessingWithStatisticsFilter()));

    averageAct = new QAction(QString::fromUtf8("Média"), this);
    averageAct->setStatusTip(QString::fromUtf8("Borra a imagem dependendo da média."));
    averageAct->setEnabled(false);
    connect(averageAct, SIGNAL(triggered()), this, SLOT(openAverageFilter()));

    weightedAverageAct = new QAction(QString::fromUtf8("Média ponderada"), this);
    weightedAverageAct->setStatusTip(QString::fromUtf8("Borra a imagem dependendo da média ponderada em relação a distância."));
    weightedAverageAct->setEnabled(false);
    connect(weightedAverageAct, SIGNAL(triggered()), this, SLOT(openWeightedAverageFilter()));

    gaussianAct = new QAction(QString::fromUtf8("Gaussiano"), this);
    gaussianAct->setStatusTip(QString::fromUtf8("Borra a imagem."));
    gaussianAct->setEnabled(false);
    connect(gaussianAct, SIGNAL(triggered()), this, SLOT(openGaussianFilter()));

    orderStatisticAct = new QAction(QString::fromUtf8("Mediana / Max / Min"), this);
    orderStatisticAct->setStatusTip(QString::fromUtf8("Tira ruído."));
    orderStatisticAct->setEnabled(false);
    connect(orderStatisticAct, SIGNAL(triggered()), this, SLOT(openOrderStatisticFilter()));

    laplacianAct = new QAction(QString::fromUtf8("Laplaciano"), this);
    laplacianAct->setStatusTip(QString::fromUtf8("Deixa as somente bordas realçadas."));
    laplacianAct->setEnabled(false);
    connect(laplacianAct, SIGNAL(triggered()), this, SLOT(openLaplacianFilter()));

    unsharpMaskingAndHighBoostFilterAct = new QAction(QString::fromUtf8("Máscara de Nitidez e Filtro de Alta Amplificação"), this);
    unsharpMaskingAndHighBoostFilterAct->setStatusTip(QString::fromUtf8("Deixa a imagem preta e branca."));
    unsharpMaskingAndHighBoostFilterAct->setEnabled(false);
    connect(unsharpMaskingAndHighBoostFilterAct, SIGNAL(triggered()), this, SLOT(openUnsharpMaskingAndHighBoostFilter()));

    gradientAct = new QAction(QString::fromUtf8("Gradiente"), this);
    gradientAct->setStatusTip(QString::fromUtf8("Detecção de bordas."));
    gradientAct->setEnabled(false);
    connect(gradientAct, SIGNAL(triggered()), this, SLOT(openGradientFilter()));


    additionAct = new QAction(QString::fromUtf8("Adição"), this);
    additionAct->setStatusTip(QString::fromUtf8("Soma as imagens."));
    additionAct->setEnabled(false);
    connect(additionAct, SIGNAL(triggered()), this, SLOT(openAdditionOperation()));

    subtractionAct = new QAction(QString::fromUtf8("Subtação"), this);
    subtractionAct->setStatusTip(QString::fromUtf8("Subitrai as imagens."));
    subtractionAct->setEnabled(false);
    connect(subtractionAct, SIGNAL(triggered()), this, SLOT(openSubtractionOperation()));

    multiplicationAct = new QAction(QString::fromUtf8("Multiplicação"), this);
    multiplicationAct->setStatusTip(QString::fromUtf8("Multiplica as imagens."));
    multiplicationAct->setEnabled(false);
    connect(multiplicationAct, SIGNAL(triggered()), this, SLOT(openMultiplicationOperation()));

    divisionAct = new QAction(QString::fromUtf8("Divisão"), this);
    divisionAct->setStatusTip(QString::fromUtf8("Divide as imagens."));
    divisionAct->setEnabled(false);
    connect(divisionAct, SIGNAL(triggered()), this, SLOT(openDivisionOperation()));


    boundaryFollowingAct = new QAction(QString::fromUtf8("Boundary Following"), this);
    boundaryFollowingAct->setStatusTip(QString::fromUtf8("Deixa só as bordas da imagem."));
    boundaryFollowingAct->setEnabled(false);
    connect(boundaryFollowingAct, SIGNAL(triggered()), this, SLOT(openBoundaryFollowingRepresentation()));

    chainCodeAct = new QAction(QString::fromUtf8("Chain Code"), this);
    chainCodeAct->setStatusTip(QString::fromUtf8("Define a borda como sendo uma sequencia de números."));
    chainCodeAct->setEnabled(false);
    connect(chainCodeAct, SIGNAL(triggered()), this, SLOT(openChainCodeRepresentation()));

    splittingAct = new QAction(QString::fromUtf8("Splitting"), this);
    splittingAct->setStatusTip(QString::fromUtf8("Representa a borda por retas mais simplificada."));
    splittingAct->setEnabled(false);
    connect(splittingAct, SIGNAL(triggered()), this, SLOT(openSplittingRepresentation()));

    basicDescriptorsAct = new QAction(QString::fromUtf8("Descritores básicos"), this);
    basicDescriptorsAct->setStatusTip(QString::fromUtf8("Descritores basicos."));
    basicDescriptorsAct->setEnabled(false);
    connect(basicDescriptorsAct, SIGNAL(triggered()), this, SLOT(openBasicDescriptors()));

    momentInvariantsDescriptorsAct = new QAction(QString::fromUtf8("Moment Invariants"), this);
    momentInvariantsDescriptorsAct->setStatusTip(QString::fromUtf8("Descritores invariantes."));
    momentInvariantsDescriptorsAct->setEnabled(false);
    connect(momentInvariantsDescriptorsAct, SIGNAL(triggered()), this, SLOT(openMomentInvariantsDescriptors()));

    histogramDescriptorsAct = new QAction(QString::fromUtf8("Histograma"), this);
    histogramDescriptorsAct->setStatusTip(QString::fromUtf8("Descritores baseados nos valores de histograma."));
    histogramDescriptorsAct->setEnabled(false);
    connect(histogramDescriptorsAct, SIGNAL(triggered()), this, SLOT(openHistogramDescriptors()));
}

void Window::closeEvent(QCloseEvent *event){
    bool e;
    while(tab->count() > 0){
        e = closeImage(tab->count() - 1);
        if(!e){
            event->ignore();
            break;
        }
    }
}

void Window::deleteLast(){
    ImageContainer *conteiner = (ImageContainer *)tab->widget(tab->count() - 1);
    tab->removeTab(tab->count() - 1);
    delete conteiner;
}

void Window::updateActions(){
    bool state = tab->count()>0;
    filterAct->setEnabled(state);
    operationAct->setEnabled(state);
    representationAct->setEnabled(state);
    pcaAct->setEnabled(state);
    normalSizeAct->setEnabled(state);
    zoomInAct->setEnabled(state);
    zoomOutAct->setEnabled(state);
    fitToWindowAct->setEnabled(state);
    viewHistogramPanelAct->setEnabled(state);

    grayscaleAct->setEnabled(state);
    negativeAct->setEnabled(state);
    logAct->setEnabled(state);
    powerAct->setEnabled(state);
    thresholdingAct->setEnabled(state);
    histogramEqualizationAct->setEnabled(state);
    histogramMatchingAct->setEnabled(state);
    localHistogramProcessingAct->setEnabled(state);
    localHistogramProcessingWithStatisticsAct->setEnabled(state);
    averageAct->setEnabled(state);
    weightedAverageAct->setEnabled(state);
    gaussianAct->setEnabled(state);
    orderStatisticAct->setEnabled(state);
    laplacianAct->setEnabled(state);
    unsharpMaskingAndHighBoostFilterAct->setEnabled(state);
    gradientAct->setEnabled(state);

    additionAct->setEnabled(state);
    subtractionAct->setEnabled(state);
    multiplicationAct->setEnabled(state);
    divisionAct->setEnabled(state);

    boundaryFollowingAct->setEnabled(state);
    chainCodeAct->setEnabled(state);
    splittingAct->setEnabled(state);
    basicDescriptorsAct->setEnabled(state);
    momentInvariantsDescriptorsAct->setEnabled(state);
    histogramDescriptorsAct->setEnabled(state);

    saveAsAct->setEnabled(state);

    updateImage();
    //colocar o save para cada imagem que tah na frente
}

void Window::updateImage(int){
    ImageContainer *child = (ImageContainer *)tab->currentWidget();

    if(!child){
        histogramPanelDock->hide();
        saveAct->setEnabled(false);
        return;
    }

    if (child->isWindowModified()){
        tab->setTabText(tab->indexOf(child), child->getName() + "*");
        saveAct->setEnabled(true);
    }else{
        tab->setTabText(tab->indexOf(child), child->getName());
        saveAct->setEnabled(false);
    }

    delete histogramPanel;
	histogramPanel = new HistogramPanel(this, child->getHistogram());
	histogramPanelDock->show();
	histogramPanelDock->setWidget(histogramPanel);
}

bool Window::closeImage(int _i){
    ImageContainer *child = (ImageContainer *)tab->widget(_i);
    if(child){
        if(child->close()){
            tab->removeTab(_i);
            updateActions();
            return true;
        }else return false;
    }
    return false;
}

//void Window::open(){
//    QString fileName = QFileDialog::getOpenFileName(this, QString::fromUtf8("Abrir arquivo"), QDir::currentPath());
//    //tr("JPG (*.jpg);;PNG (*.png);;GIF (*.gif);; XPM (*.xpm)"));
//
//
//    if (!fileName.isEmpty()){
//        ImageContainer *child = new ImageContainer(this);
//
//        if (child->loadImage(fileName)){
//            statusBar()->showMessage(QString::fromUtf8("Imagem carregada."));
//            tab->addTab(child, child->getName());
//            tab->setCurrentWidget(child);
//
//        } else{
//            child->close();
//            delete child;
//        }
//    }
//    updateActions();
//}

void Window::open(){
    QStringList files = QFileDialog::getOpenFileNames(this, QString::fromUtf8("Abrir arquivos"), QDir::currentPath());
    //tr("JPG (*.jpg);;PNG (*.png);;GIF (*.gif);; XPM (*.xpm)"));

//    QStringList list = files;
    QString fileName;
    QStringList::Iterator it = files.begin();
    while(it != files.end()) {
        fileName = (*it);
        if (!fileName.isEmpty()){
            ImageContainer *child = new ImageContainer(this);

            if (child->loadImage(fileName)){
                statusBar()->showMessage(QString::fromUtf8("Imagem carregada."));
                tab->addTab(child, child->getName());
                tab->setCurrentWidget(child);

            } else{
                child->close();
                delete child;
            }
        }
        ++it;
    }
    updateActions();
}

void Window::save(){
    ImageContainer *child = (ImageContainer *)tab->currentWidget();
    if(child){
        child->save();
        updateImage();
    }
}

void Window::saveAs(){
    ImageContainer *child = (ImageContainer *)tab->currentWidget();
    if(child){
        child->saveAs();
        updateImage();
    }
}

ImageContainer *Window::newImage(QImage *_img){
    ImageContainer *child = new ImageContainer(this);

    child->update(_img);
    tab->addTab(child, child->getName());
    tab->setCurrentWidget(child);
    return child;
}

void Window::filterDlg(QString _filter){
    ImageContainer *child = (ImageContainer *)tab->currentWidget();
    if(!child) return;

    QImage *img;
    if(openInNewTab){
        child = newImage(new QImage(*child->getImage()));
    }
    img = child->getImage();

    FilterDialog *dlg = new FilterDialog(this, img);
    dlg->show();
    if(!_filter.isEmpty()) dlg->changeFilter(_filter);

    connect(dlg, SIGNAL(done(QImage *)), child, SLOT(update(QImage *)));
    connect(dlg, SIGNAL(done()), this, SLOT(updateImage()));
}

void Window::operationDlg(QString _operation){
    if(tab->count() < 1) return;

    std::vector<QImage *> images;
    std::vector<QString> names;
    ImageContainer *img;


    for(int i = 0; i < tab->count(); i++){
        img = (ImageContainer *)tab->widget(i);
        images.push_back(img->getImage());
        names.push_back(img->getName());
    }

    OperationDialog *dlg = new OperationDialog(this, images, names);
    dlg->show();
    if(!_operation.isEmpty()) dlg->changeFilter(_operation);


    //tem que ajeitar!!! **************************************
//    ImageContainer *child = newImage(new QImage);
    ImageContainer *child = (ImageContainer *)tab->currentWidget();
    child = newImage(new QImage(*child->getImage()));

    connect(dlg, SIGNAL(done(QImage *)), child, SLOT(update(QImage *)));
    connect(dlg, SIGNAL(done()), this, SLOT(updateImage()));
    connect(dlg, SIGNAL(cancel()), this, SLOT(deleteLast()));
}

void Window::representationDlg(QString _representation){
    ImageContainer *child = (ImageContainer *)tab->currentWidget();
    if(!child) return;

    QImage *img;
    if(openInNewTab){
        child = newImage(new QImage(*child->getImage()));
    }
    img = child->getImage();

    RepresentationDialog *dlg = new RepresentationDialog(this, img);
    dlg->show();
    if(!_representation.isEmpty()) dlg->changeFilter(_representation);

    connect(dlg, SIGNAL(done(QImage *)), child, SLOT(update(QImage *)));
    connect(dlg, SIGNAL(done()), this, SLOT(updateImage()));
}

void Window::pcaDlg(){
    if(tab->count() < 1) return;

    std::vector<QImage *> images;
    std::vector<QString> names;
    ImageContainer *img;


    for(int i = 0; i < tab->count(); i++){
        img = (ImageContainer *)tab->widget(i);
        images.push_back(img->getImage());
        names.push_back(img->getName());
    }

    PCADialog *dlg = new PCADialog(this, images, names);
    dlg->show();


    //tem que ajeitar!!! **************************************
//    ImageContainer *child = newImage(new QImage);
//    ImageContainer *child = (ImageContainer *)tab->currentWidget();
//    child = newImage(new QImage(*child->getImage()));
//
//    connect(dlg, SIGNAL(done(QImage *)), child, SLOT(update(QImage *)));
//    connect(dlg, SIGNAL(done()), this, SLOT(updateImage()));
//    connect(dlg, SIGNAL(cancel()), this, SLOT(deleteLast()));
}

void Window::normalSize(){
    ImageContainer *child = (ImageContainer *)tab->currentWidget();
    if(child) child->normalSize();
}

void Window::zoomIn(){
    ImageContainer *child = (ImageContainer *)tab->currentWidget();
    if(child) child->zoomIn();
}

void Window::zoomOut(){
    ImageContainer *child = (ImageContainer *)tab->currentWidget();
    if(child) child->zoomOut();
}

void Window::fitToWindow(){
    ImageContainer *child = (ImageContainer *)tab->currentWidget();
    if(child) child->fitToWindow();
}

void Window::changeOpenInNewTab(bool _b){
    openInNewTab = _b;
}

void Window::openGrayscaleFilter(){
    filterDlg(QString::fromUtf8(GRAYSCALE));
}

void Window::openNegativeFilter(){
    filterDlg(QString::fromUtf8(NEGATIVE));
}

void Window::openLogFilter(){
    filterDlg(QString::fromUtf8(LOG));
}

void Window::openPowerFilter(){
    filterDlg(QString::fromUtf8(POWER));
}

void Window::openThresholdingFilter(){
    filterDlg(QString::fromUtf8(THRESHOLDING));
}

void Window::openHistogramEqualizationFilter(){
    filterDlg(QString::fromUtf8(HISTOGRAM_EQUALIZATION));
}

void Window::openHistogramMatchingFilter(){
    filterDlg(QString::fromUtf8(HISTOGRAM_MATCHING));
}

void Window::openLocalHistogramProcessingFilter(){
    filterDlg(QString::fromUtf8(LOCAL_HISTOGRAM_PROCESSING));
}

void Window::openLocalHistogramProcessingWithStatisticsFilter(){
    filterDlg(QString::fromUtf8(LOCAL_HISTOGRAM_PROCESSING_WITH_STATISTICS));
}

void Window::openAverageFilter(){
    filterDlg(QString::fromUtf8(AVERAGE));
}

void Window::openWeightedAverageFilter(){
    filterDlg(QString::fromUtf8(WEIGHTED_AVERAGE));
}

void Window::openGaussianFilter(){
    filterDlg(QString::fromUtf8(GAUSSIAN));
}

void Window::openOrderStatisticFilter(){
    filterDlg(QString::fromUtf8(ORDER_STATISTIC));
}

void Window::openLaplacianFilter(){
    filterDlg(QString::fromUtf8(LAPLACIAN));
}

void Window::openUnsharpMaskingAndHighBoostFilter(){
    filterDlg(QString::fromUtf8(UNSHARP_MASKING_AND_HIGHBOOST_FILTERING));
}

void Window::openGradientFilter(){
    filterDlg(QString::fromUtf8(GRADIENT));
}

void Window::openAdditionOperation(){
    operationDlg(QString::fromUtf8(ADDITION));
}

void Window::openSubtractionOperation(){
    operationDlg(QString::fromUtf8(SUBTRACTION));
}

void Window::openMultiplicationOperation(){
    operationDlg(QString::fromUtf8(MULTIPLICATION));
}

void Window::openDivisionOperation(){
    operationDlg(QString::fromUtf8(DIVISION));
}

void Window::openBoundaryFollowingRepresentation(){
    representationDlg(QString::fromUtf8(BOUNDARY_FOLLOWING));
}

void Window::openChainCodeRepresentation(){
    representationDlg(QString::fromUtf8(CHAIN_CODE));
}

void Window::openSplittingRepresentation(){
    representationDlg(QString::fromUtf8(SPLITTING));
}

void Window::openBasicDescriptors(){
    representationDlg(QString::fromUtf8(BASIC_DESCRIPTORS));
}

void Window::openMomentInvariantsDescriptors(){
    representationDlg(QString::fromUtf8(MOMENT_INVARIANTS));
}

void Window::openHistogramDescriptors(){
    representationDlg(QString::fromUtf8(HISTOGRAM_DESCRIPTOR));
}
